﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using DefeatEpidemic.Models;
using DefeatEpidemic.Common;
using LinqKit;
using DefeatEpidemic.Base;
using Microsoft.AspNetCore.Http;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Excel;
using Microsoft.AspNetCore.StaticFiles;
using System.IO;

namespace DefeatEpidemic.Controllers
{

    [SignFilter]
    public class MembersController : Controller
    {
        private readonly DefeatEpidemicContext _context;

        public MembersController(DefeatEpidemicContext context)
        {
            _context = context;
        }

        // GET: Members
        public IActionResult Index()
        {
            return View();
        }

        public ActionResult GetList(string keyword, int pageindex = 1, int pagesize = 15)
        {
            Response resp = new Response();
            try
            {
                int start = (pageindex - 1) * pagesize;
                var where = PredicateBuilder.New<Member>(true);
                if (!string.IsNullOrEmpty(keyword))
                {
                    Guid id = new Guid();                    
                    if (keyword.Length < 10)
                        where.And(u => u.name.Contains(keyword));
                    else if (!keyword.Contains("-"))
                        where.And(u => u.idcard == keyword);
                    else if (Guid.TryParse(keyword, out id))
                        where.And(u => u.family.id == id);
                }
                where.And(u => u.role_type == 1);
                var members = _context.Members
                    .Where(where);                
                resp.code = 1;
                resp.data = new { items = members.Skip(start).Take(pagesize), total = members.Count() };
            }
            catch (Exception ex)
            {
                resp.code = -1;
                resp.message = $"检索出错,{ex.Message},{ex.StackTrace}";
            }
            return Json(resp);
        }

        [HttpPost]        
        public async Task<IActionResult> Export(string keyword)
        {
            IExporter exporter = new ExcelExporter();
            var where = PredicateBuilder.New<Member>(true);
            if (!string.IsNullOrEmpty(keyword))
            {
                Guid id = new Guid();
                if (keyword.Length < 10)
                    where.And(u => u.name.Contains(keyword));
                else if (!keyword.Contains("-"))
                    where.And(u => u.idcard == keyword);
                else if (Guid.TryParse(keyword, out id))
                    where.And(u => u.family.id == id);
            }
            where.And(u => u.role_type == 1);
            var members = await _context.Members
                    .Where(where)
                    .ToListAsync();
            List<RequestModels.ExportMemberModel> list = new List<RequestModels.ExportMemberModel>();
            foreach(var member in members)
            {                
                await _context.Entry(member).Reference(d => d.community).LoadAsync();
                int cnt = 1;
                var exportmodel = new RequestModels.ExportMemberModel()
                {
                    id=cnt,
                    name = member.name,
                    address = member.community.community_name + "," + member.address,
                    carNumber = member.carNumber,
                    created_at = member.created_at,
                    idcard = member.idcard,
                    mobile = member.mobile,
                    remark = member.remark
                };
                list.Add(exportmodel);
                cnt++;
            }
            string path = $@"export\{DateTime.Now.ToString("yyyyMMdd")}";
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            string filename = Path.Combine(path, "社区人员列表_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx");            
            var result = await exporter.Export(filename, list);
            var provider = new FileExtensionContentTypeProvider();
            FileInfo fileInfo = new FileInfo(filename);
            var ext = fileInfo.Extension;
            new FileExtensionContentTypeProvider().Mappings.TryGetValue(ext, out var contenttype);
            return File(System.IO.File.ReadAllBytes(filename), contenttype ?? "application/octet-stream", fileInfo.Name);
        }
        
        // GET: Members/Details/5
        public async Task<IActionResult> Details(Guid? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var member = await _context.Members
                .FirstOrDefaultAsync(m => m.id == id);
            if (member == null)
            {
                return NotFound();
            }

            return View(member);
        }

        // GET: Members/Create
        public IActionResult Create()
        {
            return View();
        }

        // POST: Members/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("id,name,idcard,address,mobile,email,companyName,companyPlace,created_at,updated_at,remark")] Member member)
        {
            if (ModelState.IsValid)
            {
                if (_context.Members.Count(u => u.idcard == member.idcard) > 0)
                {
                    return RedirectToAction(nameof(Index));
                }
                member.id = Guid.NewGuid();
                _context.Add(member);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(member);
        }

        // GET: Members/Edit/5
        public async Task<IActionResult> Edit(Guid? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var member = await _context.Members.FindAsync(id);
            if (member == null)
            {
                return NotFound();
            }
            return View(member);
        }

        // POST: Members/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(Guid id, [Bind("id,name,idcard,address,mobile,email,companyName,companyPlace,created_at,updated_at,remark")] Member member)
        {
            if (id != member.id)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(member);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!MemberExists(member.id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(member);
        }

        // GET: Members/Delete/5
        public async Task<IActionResult> Delete(Guid? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var member = await _context.Members
                .FirstOrDefaultAsync(m => m.id == id);
            if (member == null)
            {
                return NotFound();
            }

            return View(member);
        }

        // POST: Members/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(Guid id)
        {
            Response resp = new Response();
            string managername = this.HttpContext.Session.GetString(Constants.USERID);
            var manager = _context.Managers.Where(u => u.name == managername).FirstOrDefault();
            if (manager.role_type == 2)
            {
                var member = await _context.Members.FindAsync(id);
                _context.Members.Remove(member);
                int ret= await _context.SaveChangesAsync();
                if (ret > 0)
                {
                    resp.code = 1;
                    resp.message = "删除成功";
                }
            }
            else
            {
                resp.code = -1;
                resp.message = "您没有删除权限";
            }
            //return RedirectToAction(nameof(Index));
            return Json(resp);           
        }

        private bool MemberExists(Guid id)
        {
            return _context.Members.Any(e => e.id == id);
        }
    }
}
